package com.ds.app.database;

import com.ds.app.ModuleNotFoundException;
import com.ds.common.CommonConfig;
import com.ds.common.logging.Log;
import com.ds.common.logging.LogFactory;
import com.ds.org.PersonNotFoundException;
import com.ds.org.conf.OrgConfig;
import com.ds.org.conf.OrgConstants;
import com.ds.org.conf.Query.ColumnMapping;
import com.ds.org.conf.Query.SqlClause;
import com.ds.server.eumus.ConfigCode;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Map;
import java.util.UUID;

public class DBModuleManager extends DBBaseManager{
	
		
	static DBModuleManager manager;

	private OrgConfig config;

	private boolean cacheEnabled;

	protected static Log log = LogFactory.getLog(OrgConstants.CONFIG_KEY.getType(),
			DBModuleManager.class);

	
	public static DBModuleManager getInstance() {
		if (manager == null) {
			manager = new DBModuleManager(OrgConstants.CONFIG_KEY);
		}
		return manager;
	}

	 DBModuleManager(ConfigCode configKey) {
		super(configKey);
		String enabled = CommonConfig.getValue(OrgConstants.CONFIG_KEY.getType()
				+ ".cache.enabled");
		this.cacheEnabled = Boolean.valueOf(enabled).booleanValue();
		this.config = OrgConfig.getInstance();
	}


	public DbModule createModule() {
		DbModule module = new DbModule();
		module.setID(UUID.randomUUID().toString());;
		return module;
	}


	public DbModule decodeRow(ResultSet rs,Boolean all) {
		DbModule module = new DbModule();
		SqlClause sqlClause = null;
		Map columnMap = null;
		sqlClause = config.getQuery("module").getSqlClause("basic");
		
		columnMap = sqlClause.getColumnMappings();
		String moduleId = getString(rs, columnMap.get("moduleId"));
		String moduleName = getString(rs, columnMap
				.get("moduleName"));
		Integer enabled = getInt(rs, columnMap.get("moduleEnabled"));
		Integer needRight = getInt(rs, columnMap
				.get("moduleneedRight"));

		String enName = getString(rs, columnMap.get("moduleEnName"));
		String url = getString(rs, columnMap.get("moduleUrl"));

		String icon = getString(rs, columnMap.get("icon"));
		int ifSSO = this.getInt(rs, columnMap.get("ifSSO"));
		String ssoId = getString(rs, columnMap.get("ssoId"));
		int moduleType = this.getInt(rs, columnMap
				.get("moduleType"));
		String memo = getString(rs, columnMap.get("memo"));
		String thumb = null;
		if (columnMap.get("thumb") != null) {
			thumb = getString(rs, columnMap.get("thumb"));
		}

	
		module.setIndex(getInt(rs, columnMap.get("index")));
		module.setID(moduleId);
		module.setName(moduleName);
		module.setEnabled(enabled);
		module.setEnName(enName);
		module.setUrl(url);
		module.setIcon(icon);
		module.setThumb(thumb);
		module.setNeedRight(needRight);
		module.setIfSSO(ifSSO);
		module.setSsoId(ssoId);
		module.setModuleType(moduleType);
		module.setMemo(memo);
		
		
		
		if (columnMap.get("serviceId") != null) {
			String serviceId = getString(rs, columnMap.get("serviceId"));
			module.setServiceId(serviceId);
		}
		if (columnMap.get("serviceClass") != null) {
			String serviceClass = getString(rs, columnMap.get("serviceClass"));
			module.setServiceClass(serviceClass);
		}
		if (columnMap.get("serviceProvider") != null) {
			String serviceProvider = getString(rs, columnMap.get("serviceProvider"));
			module.setServiceProvider(serviceProvider);
		}
		
		
		if (columnMap.get("serviceType") != null) {
			Integer serviceType = this.getInt(rs, columnMap.get("serviceType"));
			module.setServiceType(serviceType);
		}
		
		if (columnMap.get("serviceNumber") != null) {
			Integer serviceNumber = this.getInt(rs, columnMap.get("serviceNumber"));
			module.setServiceNumber(serviceNumber);
		}
		if (columnMap.get("feeType") != null) {
			Integer feeType = this.getInt(rs, columnMap.get("feeType"));
			module.setFeeType(feeType);
		}
		if (columnMap.get("feeValue") != null) {
			Integer feeValue = this.getInt(rs, columnMap.get("feeValue"));
			module.setFeeValue(feeValue);
		}
		
		if (columnMap.get("serviceState") != null) {
			Integer serviceState = this.getInt(rs, columnMap.get("serviceState"));
			module.setServiceState(serviceState);
		}
		if (columnMap.get("serviceLowConSumPtion") != null) {
			Integer serviceLowConSumPtion = this.getInt(rs, columnMap.get("serviceLowConSumPtion"));
			module.setServiceLowConSumPtion(serviceLowConSumPtion);
		}
		
		
		return module;

	}

	
	public synchronized DbModule loadModuleByKey(String moduleId) throws ModuleNotFoundException {
		DbModule module=null;
		try {
			module=loadBasic(moduleId);
              
        } catch (Exception e) {
            throw new ModuleNotFoundException("module '" + moduleId + "' not found!");
        } 
        return module;
	}
	
	
	public synchronized DbModule loadModuleByServiceKey(String serviceId) throws ModuleNotFoundException {
		DbModule module=null;
		try {
			module=loadModuleByServiceID(serviceId);
              
        } catch (Exception e) {
            throw new ModuleNotFoundException("module '" + serviceId + "' not found!");
        } 
        return module;
	}
	
	
	private synchronized DbModule loadBasic(String ID) throws Exception {
		ResultSet rs = null;	
		SqlClause sqlClause = null;	
		String strSql = null;
		DbModule module=null;
		Connection c = null;
		PreparedStatement ps = null;
		// 1.基本信息
		sqlClause = config.getQuery("module").getSqlClause("basic");
		if (sqlClause == null) {
			log.error("The module-query-sql is null, please specify it!");
			throw new ModuleNotFoundException();
		}
	
		try {
			strSql = buildSql(sqlClause, ID);
			c = this.getConnection();
			ps = c.prepareStatement(strSql.toString(),
					ResultSet.TYPE_SCROLL_INSENSITIVE,
					ResultSet.CONCUR_READ_ONLY);
			if (ps.execute()) {
				rs = ps.executeQuery();
			if (!rs.next()) {
				throw new ModuleNotFoundException(
						"module " + ID + " not found.");
			}
			 module=this.decodeRow(rs, true);
		} else {
			throw new ModuleNotFoundException(ID + "@" + ID);
		}
		} catch (SQLException e) {
			throw new PersonNotFoundException(e);
		} finally {
			getManager().close(ps);
			freeConnection(c);
		}
		
	    return module;
	}
	
	
	private synchronized DbModule loadModuleByServiceID(String ID) throws Exception {
		ResultSet rs = null;	
		SqlClause sqlClause = null;	
		String strSql = null;
		DbModule module=null;
		Connection c = null;
		PreparedStatement ps = null;
		// 1.基本信息
		sqlClause = config.getQuery("module").getSqlClause("basic");
		if (sqlClause == null) {
			log.error("The module-query-sql is null, please specify it!");
			throw new ModuleNotFoundException();
		}
	
		try {
			strSql = buildServiceSql(sqlClause, ID);
			c = this.getConnection();
			ps = c.prepareStatement(strSql.toString(),
					ResultSet.TYPE_SCROLL_INSENSITIVE,
					ResultSet.CONCUR_READ_ONLY);
			if (ps.execute()) {
				rs = ps.executeQuery();
			if (!rs.next()) {
				throw new ModuleNotFoundException(
						"module " + ID + " not found.");
			}
			 module=this.decodeRow(rs, true);
		} else {
			throw new ModuleNotFoundException(ID + "@" + ID);
		}
		} catch (SQLException e) {
			throw new PersonNotFoundException(e);
		} finally {
			getManager().close(ps);
			freeConnection(c);
		}
		
	    return module;
	}
	
	private String buildServiceSql(SqlClause sqlClause,String serviceId) {
		Map columnMap = sqlClause.getColumnMappings();
		String strSql = sqlClause.getMainClause();
		String strWhere = sqlClause.getWhereClause();
		String orderClause=sqlClause.getOrderClause();
		if (strWhere != null && !strWhere.equals("")) {
			
				strSql =
					strSql
					+ " "
					+ strWhere
					+ " AND "
					+ ((ColumnMapping)columnMap.get("serviceId")).getColumn()
					+ "='"
					+ serviceId
					+ "'";
			
		} else{
			strSql =
				strSql
				+ " WHERE "
				+ ((ColumnMapping)columnMap.get("serviceId")).getColumn()
				+ "='"
				+ serviceId
				+ "'";
		}
		if (orderClause!=null){
			strSql=strSql+" "+orderClause; 
		}
		
		return strSql;
	}

	private String buildSql(SqlClause sqlClause,String ID) {
		Map columnMap = sqlClause.getColumnMappings();
		String strSql = sqlClause.getMainClause();
		String strWhere = sqlClause.getWhereClause();
		String orderClause=sqlClause.getOrderClause();
		if (strWhere != null && !strWhere.equals("")) {
			
				strSql =
					strSql
					+ " "
					+ strWhere
					+ " AND "
					+ ((ColumnMapping)columnMap.get("moduleId")).getColumn()
					+ "='"
					+ ID
					+ "'";
			
		} else{
			strSql =
				strSql
				+ " WHERE "
				+ ((ColumnMapping)columnMap.get("moduleId")).getColumn()
				+ "='"
				+ ID
				+ "'";
		}
		if (orderClause!=null){
			strSql=strSql+" "+orderClause; 
		}
		
		return strSql;
	}

	
	
}
